﻿namespace Smart.Utils.Net
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;

    public class DownLoadHelper
    {
        private string m_Address;
        private int m_BlogSize;
        private static bool m_Cancle = false;
        private string m_FileName;
        private long m_FileSize;
        private string m_Folder;
        private double m_Percent;
        private long m_Position;
        private double m_Speed;
        private long m_Start;
        private string m_Target;
        private string m_Website;
        private HttpWebRequest theRequest;
        private HttpWebResponse theResponse;

        public event CancleDownloadEventHander CancleDownload;

        public event CompleteDownloadEventHander CompleteDownload;

        public event DownloadProcessEventHander DownloadProcess;

        public DownLoadHelper(string URL)
        {
            this.theResponse = null;
            this.theRequest = null;
            this.m_Target = Application.StartupPath;
            this.m_Address = "";
            this.m_FileName = "";
            this.m_FileSize = 0L;
            this.m_Position = 0L;
            this.m_Percent = 0.0;
            this.m_Speed = 0.0;
            this.m_Start = 0L;
            this.m_BlogSize = 0x1000;
            this.m_Folder = "";
            this.m_Website = "";
            this.m_FileName = URL.Split(new char[] { '/' })[URL.Split(new char[] { '/' }).Length - 1];
            this.m_Address = URL;
            this.m_Target = this.m_Target + @"\" + this.m_FileName;
            this.m_Website = URL.Substring(7, URL.IndexOf("/", 7) - 7);
        }

        public DownLoadHelper(string URL, string TargetFolder)
        {
            this.theResponse = null;
            this.theRequest = null;
            this.m_Target = Application.StartupPath;
            this.m_Address = "";
            this.m_FileName = "";
            this.m_FileSize = 0L;
            this.m_Position = 0L;
            this.m_Percent = 0.0;
            this.m_Speed = 0.0;
            this.m_Start = 0L;
            this.m_BlogSize = 0x1000;
            this.m_Folder = "";
            this.m_Website = "";
            this.m_FileName = URL.Split(new char[] { '/' })[URL.Split(new char[] { '/' }).Length - 1];
            this.m_Address = URL;
            this.m_Folder = TargetFolder;
            this.m_Target = this.m_Folder + @"\" + this.m_FileName;
        }

        private void RaiseCancleDownloadEventHander(string e)
        {
            if (this.CancleDownload != null)
            {
                this.CancleDownload(this, e);
            }
        }

        private void RaiseCompleteDownloadEventHander()
        {
            if (this.CompleteDownload != null)
            {
                this.CompleteDownload(this);
            }
        }

        private void RaiseDownloadProcessEventHander(long length, long position, double percent, double speed)
        {
            if (this.DownloadProcess != null)
            {
                this.DownloadProcess(this, length, position, percent, speed);
            }
        }

        public void Start()
        {
            try
            {
                this.theRequest = (HttpWebRequest) WebRequest.Create(this.m_Address);
                this.theResponse = (HttpWebResponse) this.theRequest.GetResponse();
            }
            catch (Exception exception)
            {
                this.RaiseCancleDownloadEventHander(exception.Message);
                return;
            }
            this.m_FileSize = this.theResponse.ContentLength;
            this.RaiseDownloadProcessEventHander(this.m_FileSize, this.m_Position, this.m_Percent, this.m_Speed);
            FileStream stream = new FileStream(this.m_Target, FileMode.Create);
            this.m_Position = 0L;
            Stopwatch stopwatch = new Stopwatch();
            this.m_Speed = -1.0;
            int num = 0;
            while (true)
            {
                if (m_Cancle)
                {
                    this.RaiseCancleDownloadEventHander("Process abort by User");
                    this.theResponse.GetResponseStream().Close();
                    stream.Close();
                    return;
                }
                stopwatch.Start();
                byte[] buffer = new byte[this.m_BlogSize];
                int count = this.theResponse.GetResponseStream().Read(buffer, 0, this.m_BlogSize);
                this.m_Position += count;
                this.m_Percent = (this.m_Position * 100L) / this.m_FileSize;
                this.RaiseDownloadProcessEventHander(this.m_FileSize, this.m_Position, this.m_Percent, this.m_Speed);
                if (count == 0)
                {
                    break;
                }
                stream.Write(buffer, 0, count);
                stopwatch.Stop();
                num++;
                if (num >= 5)
                {
                    this.m_Speed = ((double) (this.m_BlogSize * 5)) / (((double) stopwatch.ElapsedMilliseconds) / 1000.0);
                    stopwatch.Reset();
                    num = 0;
                }
            }
            this.theResponse.GetResponseStream().Close();
            stream.Close();
            if (m_Cancle)
            {
                System.IO.File.Delete(this.m_Target);
                this.RaiseCancleDownloadEventHander("Process abort by User");
            }
            else
            {
                this.RaiseCompleteDownloadEventHander();
            }
        }

        public string Address
        {
            get
            {
                return this.m_Address;
            }
            set
            {
                this.m_Address = value;
                this.m_FileName = this.m_Address.Split(new char[] { '/' })[this.m_Address.Split(new char[] { '/' }).Length - 1];
                this.m_Target = this.m_Folder + @"\" + this.m_FileName;
            }
        }

        public int BlogSize
        {
            get
            {
                return this.m_BlogSize;
            }
            set
            {
                this.m_BlogSize = value;
            }
        }

        public static bool Cancle
        {
            get
            {
                return m_Cancle;
            }
            set
            {
                m_Cancle = value;
            }
        }

        public string FileName
        {
            get
            {
                return this.m_FileName;
            }
            set
            {
                this.m_FileName = value;
            }
        }

        public long FileSize
        {
            get
            {
                return this.m_FileSize;
            }
        }

        public string Folder
        {
            get
            {
                return this.m_Folder;
            }
            set
            {
                this.m_Folder = value;
            }
        }

        public double Percent
        {
            get
            {
                return this.m_Percent;
            }
        }

        public long Position
        {
            get
            {
                return this.m_Position;
            }
        }

        public double Speed
        {
            get
            {
                return this.m_Speed;
            }
        }

        public string Target
        {
            get
            {
                return this.m_Target;
            }
            set
            {
                this.m_Target = value;
            }
        }

        public string Website
        {
            get
            {
                return this.m_Website;
            }
            set
            {
                this.m_Website = value;
            }
        }

        public delegate void CancleDownloadEventHander(object sender, string e);

        public delegate void CompleteDownloadEventHander(object sender);

        public delegate void DownloadProcessEventHander(object sender, long length, long position, double percent, double speed);

        public delegate void DownloadStatedEventHander(object sender, string e);
    }
}

